package com.nlelpct.manage.service.impl;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nlelpct.manage.constant.*;
import com.nlelpct.manage.enums.ResultEnum;
import com.nlelpct.manage.exception.CodeMsg;
import com.nlelpct.manage.feign.SMSFeignService;
import com.nlelpct.manage.mapper.*;
import com.nlelpct.manage.model.dto.SysEmployeeAddDto;
import com.nlelpct.manage.model.dto.SysEmployeeAndRoleUpdateDto;
import com.nlelpct.manage.model.dto.SysEmployeeUpdateDto;
import com.nlelpct.manage.model.dto.SysEmployeeWhetherAddDto;
import com.nlelpct.manage.model.entity.*;
import com.nlelpct.manage.model.excel.ExcelExportData;
import com.nlelpct.manage.model.excel.ExcelUtils;
import com.nlelpct.manage.model.query.InsertAndUpdateEmployeeQuery;
import com.nlelpct.manage.model.query.SysEmployeeListByPageQuery;
import com.nlelpct.manage.model.vo.*;
import com.nlelpct.manage.service.ISysEmployeeService;
import com.nlelpct.manage.service.LogBaseService;
import com.nlelpct.manage.service.SysEmployeeDepartmentService;
import com.nlelpct.manage.utils.GetLoginInfoUtils;
import com.nlelpct.manage.utils.IDUtils;
import com.nlelpct.manage.utils.MD5Utils;
import com.nlelpct.manage.utils.TimeUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.System;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @Author 刘伟涛
 * @Date 2023/7/18 16:37
 **/
@Service
public class SysEmployeeServiceImpl extends ServiceImpl<SysEmployeeMapper, SysEmployee>
        implements ISysEmployeeService {

    @Autowired
    private SysEmployeeDepartmentService sysEmployeeDepartmentService;


    @Autowired
    private UserMapper userMapper;
    @Autowired
    private SysEmployeeMapper sysEmployeeMapper;
    @Autowired
    private SysCompanyMapper sysCompanyMapper;
    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private SysEmployeeAndDeptMapper sysEmployeeAndDeptMapper;
    @Autowired
    private SysEmployeePostMapper sysEmployeePostMapper;
    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysEmployeeAndRoleMapper sysEmployeeAndRoleMapper;
    @Autowired
    private SysPhoneAreaCodeMapper sysPhoneAreaCodeMapper;
    @Autowired
    private SysPostMapper sysPostMapper;
    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;
    @Autowired
    private SysSystemMapper sysSystemMapper;
    @Autowired
    private LogBaseService logBaseService;
    @Autowired
    private SMSFeignService smsFeignService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${mobile-code.register-notice}")
    private String mobileCodeRegisterNotice;

    @Override
    public ResponseResult<String> getWhetherAdd(SysEmployeeWhetherAddDto sysEmployeeWhetherAddDto) {
/*        Map<String, String> map = new HashMap<>();
        map.put(SysSolrLogConstant.OPERATE_INFO, "2");
        map.put(SysSolrLogConstant.OPERATE_TYPE, SysOperateTypeEnum.DEL.getName());
        map.put(SysSolrLogConstant.OPERATE_CONTENT, "你好");
        map.put(SysSolrLogConstant.OPERATE_OBJ, "手机号" + sysEmployeeWhetherAddDto.getPhone());
        Object o = redisTemplate.opsForValue().get(ThreadParameter.getLocalMap().get(SystemConstant.TERMINAL_INFO));
        System.out.println("这是：" + o);

        logBaseService.saveOptLog(SysOperateTypeEnum.DEL.getIndex(), map);*/

        if (ObjectUtil.isEmpty(sysEmployeeWhetherAddDto)) {
            return ResponseResult.error(ResponseCode.ORDINARY_FAIL, ResponseMsg.NOT_INPUT_PHONE_OR_AREA_CODE);
        }
        //先查企业员工上限
        // 获取企业id
        String companyId = GetLoginInfoUtils.getCompanyId();
        String systemId = GetLoginInfoUtils.getSystemId();

        Integer maxNum = sysCompanyMapper.selectMaxLimitByCompanyId(companyId, systemId);
        //获取该企业下的员工数量
        int employeeNum = sysEmployeeMapper.countByEmployeeStatusByCompanyId(companyId, systemId, SysEmployeeConstant.NOT_DEL_FLAG);
        if (maxNum.compareTo(employeeNum) <= 0) {
            return ResponseResult.error(CodeMsg.EMPLOYEE_CEILING.getCode(), CodeMsg.EMPLOYEE_CEILING.getMsg());
        }

        //再查企业的员工是否存在该手机号
        int countEmployee = sysEmployeeMapper.countByPhone(sysEmployeeWhetherAddDto, companyId, systemId, SysEmployeeConstant.NOT_DEL_FLAG);
        if (countEmployee > 0) {
            return ResponseResult.error(CodeMsg.EMPLOYEE_EXIST.getCode(), CodeMsg.EMPLOYEE_EXIST.getMsg());
        }

        //再查用户是否存在该手机号,不存在会进行注册
        UserByPhoneVo userByPhoneVo = userMapper.selectByPhone(sysEmployeeWhetherAddDto.getPhone(), sysEmployeeWhetherAddDto.getAreaCode());
        if (ObjectUtil.isEmpty(userByPhoneVo)) {
            return ResponseResult.error(CodeMsg.USER_NOT_FOUND.getCode(), CodeMsg.USER_NOT_FOUND.getMsg());
        }

        //查询手机号是否禁用
        Integer enableStatus = 1;
        if (!enableStatus.equals(userByPhoneVo.getZt())) {
            return ResponseResult.error(CodeMsg.USER_DISABLE.getCode(), CodeMsg.USER_DISABLE.getMsg());
        } else {
            return ResponseResult.success(ResponseMsg.AGREE_ADD);
        }
    }

    @Override
    public ResponseResult<Boolean> getEmployeeNumberWhetherExist(InsertAndUpdateEmployeeQuery validateEmployeeQuery) {
        LambdaQueryWrapper<SysEmployee> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysEmployee::getEmployeeNum, validateEmployeeQuery.getEmployeeNum())
                .eq(SysEmployee::getCompanyId, GetLoginInfoUtils.getCompanyId())
                .eq(SysEmployee::getSystemId, GetLoginInfoUtils.getSystemId())
                .eq(SysEmployee::getDelFlag, SysEmployeeConstant.NOT_DEL_FLAG);

        SysEmployee sysEmployee = sysEmployeeMapper.selectOne(lambdaQueryWrapper);
        if (ObjectUtils.isEmpty(sysEmployee)) {
            return ResponseResult.success(true, CodeMsg.EMPLOYEE_NUM_NOT_EXIST);
        }
        if (sysEmployee.getEmployeeId().equals(validateEmployeeQuery.getEmployeeId())) {
            return ResponseResult.success(true, CodeMsg.EMPLOYEE_NUM_NOT_EXIST);
        }
        return ResponseResult.success(false, CodeMsg.EMPLOYEE_NUM_EXIST.getMsg());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResponseResult<String> addEmployee(InsertAndUpdateEmployeeQuery insertEmployeeQuery) {

        if (ObjectUtil.isEmpty(insertEmployeeQuery)) {
            return ResponseResult.error(ResponseCode.ORDINARY_FAIL);
        }
        String userId;
        String phone = insertEmployeeQuery.getPhone();
        String companyId = GetLoginInfoUtils.getCompanyId();
        String systemId = GetLoginInfoUtils.getSystemId();
        String loginEmployeeId = GetLoginInfoUtils.getEmployeeId();

        //先查企业员工上限
        Integer maxNum = sysCompanyMapper.selectMaxLimitByCompanyId(companyId, systemId);
        //获取该企业下的员工数量
        int employeeNum = sysEmployeeMapper.countByEmployeeStatusByCompanyId(companyId, systemId, SysEmployeeConstant.NOT_DEL_FLAG);
        if (maxNum.compareTo(employeeNum) <= 0) {
            return ResponseResult.error(CodeMsg.EMPLOYEE_CEILING.getCode(), CodeMsg.EMPLOYEE_CEILING.getMsg());
        }

        //再查企业是否存在该手机号
        SysEmployeeWhetherAddDto sysEmployeeWhetherAddDto = new SysEmployeeWhetherAddDto();
        sysEmployeeWhetherAddDto.setPhone(phone);
        sysEmployeeWhetherAddDto.setAreaCode(SysEmployeeConstant.AREA_CODE);
        int countEmployee = sysEmployeeMapper.countByPhone(sysEmployeeWhetherAddDto, companyId, systemId, SysEmployeeConstant.NOT_DEL_FLAG);
        if (countEmployee > 0) {
            return ResponseResult.error(CodeMsg.EMPLOYEE_EXIST.getCode(), CodeMsg.EMPLOYEE_EXIST.getMsg());
        }

        //查用户表是否存在该手机号
        UserByPhoneVo userByPhoneVo = userMapper.selectByPhone(phone, insertEmployeeQuery.getAreaCode());
        if (ObjectUtil.isEmpty(userByPhoneVo)) {
            String password = MD5Utils.getMD5String(phone.substring(phone.length() - 6));
            User user = new User()
                    .setId(IDUtils.getUUID())
                    .setPhone(phone)
                    .setEmail(insertEmployeeQuery.getEmployeeMail())
                    .setPassword(password)
                    .setCjsj(LocalDateTime.now())
                    .setZt(SystemConstant.USER_STATUS_NORMAL)
                    .setUsername("-")
                    .setLastResetPasswd(LocalDateTime.now())
                    .setAreaCode("86");
            userMapper.insert(user);
            userId = user.getId();

            // 发手机短信
            /*LiveSMSVo live = new LiveSMSVo();
            Map<String, String> param = new HashMap<>();
            live.setMobile(phone);
            live.setModelCode(mobileCodeRegisterNotice);
            param.put("xtmc", sysSystemMapper.selectById(GetLoginInfoUtils.getSystemId()).getSystemName());
            param.put("qymc", sysCompanyMapper.selectById(GetLoginInfoUtils.getCompanyId()).getCompanySysName());
            param.put("yhsjhm", phone);
            param.put("yhcsmm", password);
            param.put("czrsjhm", userMapper.selectUserIdByPhone(sysEmployeeMapper.selectById(GetLoginInfoUtils.getEmployeeId()).getUserId(), "86"));
            live.setParams(param);
            try {
                smsFeignService.sendSMS(live);
            } catch (Exception e) {
                log.error("调用短信发送接口失败！");
                e.printStackTrace();
            }*/
        } else {
            //查询手机号是否禁用
            Integer enableStatus = 1;
            if (!enableStatus.equals(userByPhoneVo.getZt())) {
                return ResponseResult.error(CodeMsg.USER_DISABLE.getCode(), CodeMsg.USER_DISABLE.getMsg());
            }
            userId = userByPhoneVo.getId();
        }
        //添加员工表
        //员工工号已存在
        LambdaQueryWrapper<SysEmployee> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysEmployee::getEmployeeNum, insertEmployeeQuery.getEmployeeNum())
                .eq(SysEmployee::getCompanyId, companyId)
                .eq(SysEmployee::getSystemId, systemId)
                .eq(SysEmployee::getDelFlag, SysEmployeeConstant.NOT_DEL_FLAG);
        Long count = sysEmployeeMapper.selectCount(lambdaQueryWrapper);
        if (count > 0) {
            return ResponseResult.error(CodeMsg.EMPLOYEE_NUM_EXIST.getCode(), CodeMsg.EMPLOYEE_NUM_EXIST.getMsg());
        }
        SysEmployee sysEmployee = new SysEmployee();
        BeanUtils.copyProperties(insertEmployeeQuery, sysEmployee);
        sysEmployee.setCompanyId(companyId);
        sysEmployee.setSystemId(systemId);
        sysEmployee.setUserId(userId);
        sysEmployee.setCreateTime(System.currentTimeMillis());
        sysEmployee.setCreateBy(loginEmployeeId);
        sysEmployeeMapper.insert(sysEmployee);

        //添加员工部门关联表
        String employeeId = sysEmployee.getEmployeeId();
        SysEmployeeAndDept sysEmployeeAndDept = new SysEmployeeAndDept();
        sysEmployeeAndDept.setDeptId(insertEmployeeQuery.getDeptId());
        sysEmployeeAndDept.setEmployeeId(employeeId);
        sysEmployeeAndDeptMapper.insert(sysEmployeeAndDept);

        //添加员工岗位关联表
        String postId = insertEmployeeQuery.getPostId();
        if (!ObjectUtil.isEmpty(postId)) {
            SysEmployeePost sysEmployeePost = new SysEmployeePost();
            sysEmployeePost.setEmployeeId(employeeId);
            sysEmployeePost.setPostId(postId);
            sysEmployeePostMapper.insert(sysEmployeePost);
        }
        //添加员工时，部门已存在负责人，则不允许设为负责人。
        if (insertEmployeeQuery.getIsDeptLeader()) {
            SysDept sysDept = sysDeptMapper.selectById(insertEmployeeQuery.getDeptId());
            if (StringUtils.isNotBlank(sysDept.getLeaderEmployeeId())) {
                return ResponseResult.error(CodeMsg.LEADER_EMPLOYEE_EXIST.getCode(), CodeMsg.LEADER_EMPLOYEE_EXIST.getMsg());
            } else {
                sysDeptMapper.updateByDeptId(insertEmployeeQuery.getDeptId(), employeeId, System.currentTimeMillis(), loginEmployeeId);
            }
        }
        return ResponseResult.success(ResponseMsg.ADD_SUCCESS);
    }

    @Override
    public ResponseResult<PageResultVo<SysEmployeeListByPageVo>> getAllByPage(SysEmployeeListByPageQuery sysEmployeeListByPageQuery) {
        // 获取企业id
        String companyId = GetLoginInfoUtils.getCompanyId();

        Page<SysEmployeeListByPageVo> page = new Page<>(Optional.ofNullable(sysEmployeeListByPageQuery.getPageNum()).orElse(1), Optional.ofNullable(sysEmployeeListByPageQuery.getPageSize()).orElse(10));
        Page<SysEmployeeListByPageVo> pageSysEmployees = sysEmployeeMapper.selectAllByPage(page, sysEmployeeListByPageQuery, companyId, GetLoginInfoUtils.getSystemId(), SysEmployeeConstant.NOT_DEL_FLAG);

        List<SysEmployeeListByPageVo> records = pageSysEmployees.getRecords();
        records.forEach(sysEmployeeListByPageVo -> {
            //员工和岗位一对多
/*            List<String> postIdList = sysEmployeePostMapper.selectPostIdsByEmployeeId(sysEmployeeListByPageVo.getEmployeeId());
            if(!ObjectUtils.isEmpty(postIdList)){
                List<SysPost> sysPosts = sysPostMapper.selectBatchIds(postIdList);
                StringBuilder postName = new StringBuilder();
                sysPosts.forEach(sysPost -> postName.append(sysPost.getPostZhName()));
                sysEmployeeListByPageVo.setPostZhName(postName.toString());
                }*/
            //员工和岗位一对一
            String postId = sysEmployeePostMapper.selectPostIdByEmployeeId(sysEmployeeListByPageVo.getEmployeeId());
            if (!ObjectUtils.isEmpty(postId)) {
                SysPost sysPost = sysPostMapper.selectById(postId);
                if (!ObjectUtils.isEmpty(sysPost)) {
                    sysEmployeeListByPageVo.setPostZhName(sysPost.getPostZhName());
                    sysEmployeeListByPageVo.setPostEsName(sysPost.getPostEsName());
                }
            }

        });
        return ResponseResult.success(new PageResultVo<>(pageSysEmployees.getRecords(), pageSysEmployees.getTotal()));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResponseResult<String> updateEmployeeStatus(String employeeId) {
        // 获取企业id
        String companyId = GetLoginInfoUtils.getCompanyId();
        String systemId = GetLoginInfoUtils.getSystemId();
        String loginEmployeeId = GetLoginInfoUtils.getEmployeeId();

        //判断是否有操作权限
        List<String> roleIdList = sysEmployeeAndRoleMapper.selectRoleIdsByEmployeeId(loginEmployeeId);
        if(ObjectUtil.isEmpty(roleIdList)){
            return ResponseResult.error(CodeMsg.DATA_ERROR.getCode(), CodeMsg.DATA_ERROR.getMsg());
        }
        if(judgePermission(roleIdList, systemId, companyId, employeeId, loginEmployeeId)){
//            return ResponseResult.error(ResultEnum.MENU_ID_NOT_EXIST.getStatus(), ResultEnum.MENU_ID_NOT_EXIST.getMsg());
            return ResponseResult.error(CodeMsg.INSUFFICIENT_AUTHORITY.getCode(), CodeMsg.INSUFFICIENT_AUTHORITY.getMsg());
        }
        //有操作权限，且当前启用状态的员工数量未到企业license上限，开关响应操作为启用
        SysEmployee sysEmployeeForStatus = sysEmployeeMapper.selectById(employeeId);
        Integer employeeStatus = sysEmployeeForStatus.getEmployeeStatus();
        int employeeStatusAcquiesce = 0;
        if (employeeStatus == 0) {
            Integer maxNum = sysCompanyMapper.selectMaxLimitByCompanyId(companyId, systemId);
            //获取该企业下的员工数量
            int employeeNum = sysEmployeeMapper.countByEmployeeStatusByCompanyId(companyId, systemId, SysEmployeeConstant.NOT_DEL_FLAG);
            if (maxNum.compareTo(employeeNum) <= 0) {
                return ResponseResult.error(CodeMsg.EMPLOYEE_CEILING.getCode(), CodeMsg.EMPLOYEE_CEILING.getMsg());
            }
            employeeStatusAcquiesce = 1;
        }
        SysEmployee sysEmployee = new SysEmployee();
        sysEmployee.setEmployeeId(employeeId);
        sysEmployee.setEmployeeStatus(employeeStatusAcquiesce);

        sysEmployeeMapper.updateById(sysEmployee);
        //todo 是否要修改用户表对应的状态
        return ResponseResult.success(ResponseMsg.UPDATE_SUCCESS);
    }

    /**
     * 判断是否有操作员工状态权限
     * @param roleIdList 角色id列表
     * @param systemId 系统id
     * @param companyId 企业id
     * @param employeeId 员工id
     * @param loginEmployeeId 登录的员工id
     * @return 结果
     */
    public boolean judgePermission(List<String> roleIdList, String systemId, String companyId, String employeeId, String loginEmployeeId){
        //数据范围（1：全部数据权限 2：本部门数据权限 3：本部门及以下数据权限 4：归属本人的数据 5：自定数据权限）
            List<SysRole> sysRoles = sysRoleMapper.selectBatchIds(roleIdList);
            List<Integer> dataScopeList = sysRoles.stream().map(SysRole::getDataScope)
                    .collect(Collectors.toList());
            if (!ObjectUtils.isEmpty(dataScopeList)){
                //不包含全部数据权限
                if(!dataScopeList.contains(SysRoleConstant.DATA_SCOPE_ALL_DATA)){
                    //包含自定义权限时
                    if(dataScopeList.contains(SysRoleConstant.DATA_SCOPE_CUSTOM)){
                        List<String> roleIds = sysRoles.stream()
                                .filter(sysRole -> sysRole.getDataScope() == SysRoleConstant.DATA_SCOPE_CUSTOM)
                                .map(SysRole::getRoleId).collect(Collectors.toList());
                        LambdaQueryWrapper<SysMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                        lambdaQueryWrapper.eq(SysMenu::getMenuCode, "sysEmployeeIsEnable")
                                .eq(SysMenu::getSystemId, systemId);
                        String menuId = sysMenuMapper.selectOne(lambdaQueryWrapper).getMenuId();
                        //不包含修改权限时
                        if(sysRoleMenuMapper.selectByRoleIds(roleIds).contains(menuId)){
                            return judgeDeptHereinafter(dataScopeList,employeeId,loginEmployeeId,companyId);
                        }
                    }else {
                        return judgeDeptHereinafter(dataScopeList,employeeId,loginEmployeeId,companyId);
                    }
                }

            }
        return false;
    }

    /**
     * 判断部门及一下
     * @param dataScopeList
     * @param employeeId
     * @param loginEmployeeId
     * @param companyId
     * @return
     */
    public boolean judgeDeptHereinafter(List<Integer> dataScopeList,String employeeId, String loginEmployeeId, String companyId){
        String deptId = sysEmployeeAndDeptMapper.selectDeptIdByEmployeeId(employeeId);
        String loginDeptId = sysEmployeeAndDeptMapper.selectDeptIdByEmployeeId(loginEmployeeId);
        //包含本部门及以下数据权限
        if(dataScopeList.contains(SysRoleConstant.DATA_SCOPE_DEPARTMENT_AND_BELOW)){
            LambdaQueryWrapper<SysDept> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(SysDept::getParentId, loginDeptId)
                    .eq(SysDept::getCompanyId, companyId);
            List<SysDept> sysDepts = sysDeptMapper.selectList(lambdaQueryWrapper);
            List<String> sysDeptIds = new ArrayList<>();
            sysDeptIds.add(loginDeptId);
            while (!ObjectUtil.isEmpty(sysDepts)){
                List<String> deptIds = sysDepts.stream().map(SysDept::getDeptId).collect(Collectors.toList());
                sysDeptIds.addAll(deptIds);
                sysDepts.clear();
                deptIds.forEach(id->{
                    LambdaQueryWrapper<SysDept> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper1.eq(SysDept::getParentId, id)
                            .eq(SysDept::getCompanyId, companyId);
                    List<SysDept> sysDepts1 = sysDeptMapper.selectList(lambdaQueryWrapper1);
                    if(!ObjectUtil.isEmpty(sysDepts1)){
                        sysDepts.addAll(sysDepts1);
                    }
                });
            }
            //不是本部门及以下
            if(ObjectUtil.isEmpty(sysDeptIds) || !sysDeptIds.contains(deptId)){
                return true;
            }
        }else {
            //包含本部门数据权限
            if(dataScopeList.contains(SysRoleConstant.DATA_SCOPE_DEPARTMENT)){
                //不是本部门
                if(!loginDeptId.equals(deptId)){
                    return true;
                }
            }else {
                //不是本人
                if(!loginEmployeeId.equals(employeeId)){
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public ResponseResult<InsertAndUpdateEmployeeQuery> getEmployeeBaseInfo(String employeeId) {
        boolean isDeptLeader = false;
        InsertAndUpdateEmployeeQuery sysEmployeeUpdateVo = sysEmployeeMapper.selectByIdAndSystemIdAndCompanyId(employeeId, SysEmployeeConstant.NOT_DEL_FLAG);
        Optional.ofNullable(sysEmployeePostMapper.selectPostIdByEmployeeId(employeeId)).ifPresent(sysEmployeeUpdateVo::setPostId);
        //员工和部门是一对一关系
        SysDept sysDept = sysDeptMapper.selectById(sysEmployeeUpdateVo.getDeptId());
        if(ObjectUtils.isEmpty(sysDept)){
            return ResponseResult.error(CodeMsg.DATA_ERROR.getCode(), CodeMsg.DATA_ERROR.getMsg());
        }
        if (employeeId.equals(sysDept.getLeaderEmployeeId())) {
            isDeptLeader = true;
        }
        sysEmployeeUpdateVo.setIsDeptLeader(isDeptLeader);
        return ResponseResult.success(sysEmployeeUpdateVo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResponseResult<String> updateEmployeeBaseInfo(InsertAndUpdateEmployeeQuery updateEmployeeQuery) {
        String employeeId = updateEmployeeQuery.getEmployeeId();
        String deptId = updateEmployeeQuery.getDeptId();
        String loginEmployeeId = GetLoginInfoUtils.getEmployeeId();

        if (ObjectUtils.isEmpty(sysEmployeeMapper.selectById(employeeId))) {
            return ResponseResult.error(CodeMsg.DATA_ERROR.getCode(), CodeMsg.DATA_ERROR.getMsg());
        }
        //修改员工表
        SysEmployee sysEmployee = new SysEmployee();
        BeanUtils.copyProperties(updateEmployeeQuery, sysEmployee);
        sysEmployee.setUpdateTime(System.currentTimeMillis());
        sysEmployee.setUpdateBy(loginEmployeeId);
        sysEmployeeMapper.updateById(sysEmployee);

        //修改员工和岗位关联表
        SysEmployeePost sysEmployeePost = new SysEmployeePost();
        sysEmployeePost.setEmployeeId(employeeId);
        sysEmployeePost.setPostId(updateEmployeeQuery.getPostId());
        sysEmployeePostMapper.deleteById(employeeId);
        sysEmployeePostMapper.insert(sysEmployeePost);

        //修改员工和部门关联表
        SysEmployeeAndDept sysEmployeeAndDept = new SysEmployeeAndDept();
        sysEmployeeAndDept.setEmployeeId(employeeId);
        sysEmployeeAndDept.setDeptId(deptId);
        sysEmployeeAndDeptMapper.updateById(sysEmployeeAndDept);

        //部门负责人，修改时，部门负责人存在依然可以进行修改。添加时，部门负责人存在不可以进行修改
        SysDept sysDept = sysDeptMapper.selectById(deptId);
        String leaderEmployeeId = sysDept.getLeaderEmployeeId();
        if (updateEmployeeQuery.getIsDeptLeader()) {
            sysDeptMapper.updateByDeptId(deptId, employeeId, System.currentTimeMillis(), loginEmployeeId);
        } else {
            //将该员工取消部门负责人
            if (employeeId.equals(leaderEmployeeId)) {
                sysDeptMapper.updateByDeptId(deptId, "", System.currentTimeMillis(), loginEmployeeId);
            }
        }
        return ResponseResult.success(ResponseMsg.UPDATE_SUCCESS);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResponseResult<String> updateEmployeePassword(String employeeId) {
        SysEmployee sysEmployee = sysEmployeeMapper.selectById(employeeId);
        String userId = sysEmployee.getUserId();
        User user = userMapper.selectById(userId);
        String phone = user.getPhone();
        String password = phone.substring(phone.length() - 6);
        password = MD5Utils.getMD5String(password);
        LocalDateTime updateTime = new Timestamp(System.currentTimeMillis()).toLocalDateTime();
        user.setPassword(password);
        user.setLastResetPasswd(updateTime);
        user.setXgsj(updateTime);
        userMapper.updateById(user);
        return ResponseResult.success(ResponseMsg.RESET_PASSWORD_SUCCESS);
    }

    @Override
    public ResponseResult<List<SysDeptListVo>> getDeptList() {
        String companyId = GetLoginInfoUtils.getCompanyId();
        LambdaUpdateWrapper<SysDept> queryWrapper = new LambdaUpdateWrapper<>();
        queryWrapper.eq(SysDept::getDelFlag, SysDeptConstant.NOT_DELETE).eq(SysDept::getDeptStatus, 1).eq(SysDept::getCompanyId, companyId);
        List<SysDept> sysDepts = sysDeptMapper.selectList(queryWrapper);
        //先获得父类id集合
        Map<String, List<SysDeptListVo>> collect = sysDepts.stream().map(sysDept -> {
            SysDeptListVo sysDeptListVo = new SysDeptListVo();
            sysDeptListVo.setDeptId(sysDept.getDeptId());
            sysDeptListVo.setDeptName(sysDept.getDeptName());
            sysDeptListVo.setParentId(sysDept.getParentId());
            return sysDeptListVo;
        }).collect(Collectors.groupingBy(SysDeptListVo::getParentId));
        //获得一级集合类
        List<SysDeptListVo> sysDeptListFirstVos = collect.get("");
        for (SysDeptListVo sysDeptListFirstVo : sysDeptListFirstVos) {
            String deptIdSecond = sysDeptListFirstVo.getDeptId();
            //获得二级集合类
            List<SysDeptListVo> sysDeptListSecondVos = collect.get(deptIdSecond);
            if (ObjectUtil.isEmpty(sysDeptListSecondVos)) {
                continue;
            }
            for (SysDeptListVo sysDeptListSecondVo : sysDeptListSecondVos) {
                String deptIdThird = sysDeptListSecondVo.getDeptId();
                //获得三级集合类
                List<SysDeptListVo> sysDeptListThirdVos = collect.get(deptIdThird);
                if (ObjectUtil.isEmpty(sysDeptListThirdVos)) {
                    continue;
                }
                sysDeptListSecondVo.setSysDeptList(sysDeptListThirdVos);
            }
            sysDeptListFirstVo.setSysDeptList(sysDeptListSecondVos);
        }
        return ResponseResult.success(sysDeptListFirstVos);
    }

    @Override
    public ResponseResult<List<SysRoleListVo>> getRoleList(String employeeId) {
        if (ObjectUtil.isEmpty(employeeId)) {
            return ResponseResult.error(ResponseCode.ORDINARY_FAIL);
        }
        String companyId = GetLoginInfoUtils.getCompanyId();
        LambdaUpdateWrapper<SysRole> sysRoleQueryWrapper = new LambdaUpdateWrapper<>();
        sysRoleQueryWrapper.eq(SysRole::getDelFlag, SysRoleConstant.NOT_DELETE)
                .eq(SysRole::getRoleStatus, SysRoleConstant.STATUS_NOT_DEACTIVATE)
                .eq(SysRole::getCompanyId, companyId)
                .orderBy(true, true, SysRole::getRoleName);
        List<SysRole> sysRoles = sysRoleMapper.selectList(sysRoleQueryWrapper);

        //角色列表中员工拥有的角色做标记
        List<SysRoleListVo> sysRoleListVos = new ArrayList<>();
        //如果没有查询到角色列表，直接返回
        if (ObjectUtil.isEmpty(sysRoles)) {
            ResponseResult.success(sysRoleListVos);
        }
        //查询员工拥有的角色
        LambdaUpdateWrapper<SysEmployeeAndRole> sysEmployeeAndRoleQueryWrapper = new LambdaUpdateWrapper<>();
        sysEmployeeAndRoleQueryWrapper.eq(SysEmployeeAndRole::getEmployeeId, employeeId);
        List<SysEmployeeAndRole> sysEmployeeAndRoles = sysEmployeeAndRoleMapper.selectList(sysEmployeeAndRoleQueryWrapper);
        sysRoleListVos = sysRoles.stream().map(sysRole -> {
            SysRoleListVo sysRoleListVo = new SysRoleListVo();
            sysRoleListVo.setRoleId(sysRole.getRoleId());
            sysRoleListVo.setRoleName(sysRole.getRoleName());
            boolean enableStatus = false;
            if (!ObjectUtil.isEmpty(sysEmployeeAndRoles)) {
                for (SysEmployeeAndRole sysEmployeeAndRole : sysEmployeeAndRoles) {
                    if (sysEmployeeAndRole.getRoleId().equals(sysRole.getRoleId())) {
                        enableStatus = true;
                        break;
                    }
                }
            }
            sysRoleListVo.setEnableStatus(enableStatus);
            return sysRoleListVo;
        }).collect(Collectors.toList());
        return ResponseResult.success(sysRoleListVos);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResponseResult<String> updateEmployeeAndRole(SysEmployeeAndRoleUpdateDto sysEmployeeAndRoleUpdateDto) {
        if (ObjectUtil.isEmpty(sysEmployeeAndRoleUpdateDto)) {
            return ResponseResult.error(ResponseCode.ORDINARY_FAIL, ResponseMsg.SET_ROLE_FAIL);
        }
        String employeeId = sysEmployeeAndRoleUpdateDto.getEmployeeId();
        sysEmployeeAndRoleMapper.deleteById(employeeId);

        List<SysEmployeeAndRole> sysEmployeeAndRoles = new ArrayList<>();
        List<String> roleIdList = sysEmployeeAndRoleUpdateDto.getRoleIdList();
        if (!ObjectUtil.isEmpty(roleIdList)) {
            for (String roleId : roleIdList) {
                SysEmployeeAndRole sysEmployeeAndRole = new SysEmployeeAndRole();
                sysEmployeeAndRole.setEmployeeId(employeeId);
                sysEmployeeAndRole.setRoleId(roleId);
                sysEmployeeAndRoles.add(sysEmployeeAndRole);
            }
            sysEmployeeAndRoleMapper.insertBatch(sysEmployeeAndRoles);
        }
        return ResponseResult.success(ResponseMsg.SET_ROLE_SUCCESS);
    }

    @Override
    public ResponseResult<List<SysPhoneAreaCode>> getAreaCodeList() {
        return ResponseResult.success(sysPhoneAreaCodeMapper.selectList(null));
    }

    @Override
    public ResponseResult<List<SysPostListVo>> getPostList() {
        String companyId = GetLoginInfoUtils.getCompanyId();
        List<SysPostListVo> sysPostListVos = sysPostMapper.selectByCompanyId(companyId);
        return ResponseResult.success(sysPostListVos);
    }

    @Override
    public void exportEmployeeInfo(List<String> employeeIds, HttpServletResponse response) {
        //构建数据
        List<SysEmployee> sysEmployees = sysEmployeeMapper.selectBatchIds(employeeIds);
        if (ObjectUtils.isEmpty(sysEmployees)) {
            return;
        }
        List<SysEmployeeListVo> sysEmployeeListVos = new ArrayList<>();
        sysEmployees.forEach(sysEmployee -> sysEmployeeListVos.add(composeEmployeeExportData(sysEmployee)));

        //构建excelExportData
        ExcelExportData excelExportData = new ExcelExportData()
                .setFileName(SystemConstant.EMPLOYEE_EXCEL_FILE_PRE + TimeUtils.getTime("yyyyMMdd") + SystemConstant.EXCEL_FILE_SUFFIX)
                .setResponse(response)
                .setList(sysEmployeeListVos)
                .setSheetName(SystemConstant.EMPLOYEE_SHEET_NAME)
                .setClazz(SysEmployeeListVo.class);

        //构建并下载
        try {
            ExcelUtils.exportExcel(excelExportData);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public ResponseResult<List<SysEmployee>> getSysEmployeeList() {
        LambdaQueryWrapper<SysEmployee> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysEmployee::getCompanyId, GetLoginInfoUtils.getCompanyId())
                .eq(SysEmployee::getSystemId, GetLoginInfoUtils.getSystemId())
                .eq(SysEmployee::getDelFlag, SysEmployeeConstant.NOT_DEL_FLAG)
                .eq(SysEmployee::getEmployeeStatus, SysEmployeeConstant.STATUS_NOT_DEACTIVATE);
        return ResponseResult.success(sysEmployeeMapper.selectList(lambdaQueryWrapper));

    }


    /**
     * 返回导出员工信息
     */
    private SysEmployeeListVo composeEmployeeExportData(SysEmployee sysEmployee) {
        String employeeId = sysEmployee.getEmployeeId();
        SysEmployeeListVo sysEmployeeListVo = new SysEmployeeListVo();
        BeanUtils.copyProperties(sysEmployee, sysEmployeeListVo);
        //是否启用
        sysEmployeeListVo.setEmployeeStatus(sysEmployee.getEmployeeStatus() == 1 ? "启用" : "禁用");
        //创建时间
        sysEmployeeListVo.setCreateTime(TimeUtils.getTime(new Date(sysEmployee.getCreateTime()), "yyyy-MM-dd HH:mm:ss"));
        //最后登录时间
        Optional.ofNullable(sysEmployee.getLastLogin())
                .ifPresent(lastLogin -> sysEmployeeListVo.setLastLogin(TimeUtils.getTime(new Date(lastLogin), "yyyy-MM-dd HH:mm:ss")));
        //手机号
        sysEmployeeListVo.setPhone(userMapper.selectById(sysEmployee.getUserId()).getPhone());
        //所属部门
        List<String> deptIds = sysEmployeeAndDeptMapper.selectDeptIdsByEmployeeId(employeeId);
        List<String> deptNameList = sysDeptMapper.selectDeptNamesByDeptIds(deptIds);
        sysEmployeeListVo.setDeptName(deptNameList.toString());
        //岗位名称
        Optional.ofNullable(sysEmployeePostMapper.selectPostIdByEmployeeId(employeeId)).ifPresent(postId -> {
            SysPost sysPost = sysPostMapper.selectById(postId);
            sysEmployeeListVo.setPostZhName(sysPost.getPostZhName());
        });
        //所属角色
        Optional.ofNullable(sysEmployeeAndRoleMapper.selectRoleIdsByEmployeeId(employeeId)).ifPresent(roleIds -> {
            List<String> roleNameList = sysRoleMapper.selectRoleNamesByRoleIds(roleIds);
            sysEmployeeListVo.setRoleName(roleNameList.toString());
        });
        return sysEmployeeListVo;
    }


    @Override
    public ResponseResult<List<SysEmployee>> getSysEmployeeListByDeptIds(List<String> deptIds) {

        List<SysEmployeeAndDept> sysEmployeeAndDeptList = sysEmployeeDepartmentService.getSysEmployeeAndDeptByDeptIds(deptIds);
        List<SysEmployee> sysEmployeeList = new ArrayList<>();
        if (ArrayUtil.isNotEmpty(sysEmployeeAndDeptList)) {
            List<String> employeeIds = sysEmployeeAndDeptList.stream().map(o -> o.getEmployeeId()).collect(Collectors.toList());

            LambdaQueryWrapper<SysEmployee> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(SysEmployee::getCompanyId, GetLoginInfoUtils.getCompanyId())
                    .eq(SysEmployee::getSystemId, GetLoginInfoUtils.getSystemId()).in(SysEmployee::getEmployeeId, employeeIds);

            sysEmployeeList = sysEmployeeMapper.selectList(lambdaQueryWrapper);

        }

        return ResponseResult.success(sysEmployeeList);

    }
}




